package com.dys.controller;

import com.dys.entity.Student;
import com.dys.service.StudentService;
import com.dys.service.impl.StudentServiceImpl;
import com.dys.util.PageUtil;
import com.google.gson.Gson;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.Date;
import java.util.Arrays;
import java.util.List;

/**
 * @className: com.dys.controller.StudentServlet
 * @description: 学生Servlet
 * @author: pine cone
 * @version: v1.0.0
 * @createTime: 2024/10/09 22:19
 */
@WebServlet(urlPatterns = "/offlineSchool/studentServlet.do")
public class StudentServlet extends HttpServlet {
    private StudentService studentService = new StudentServiceImpl();

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if ("saveStudent".equals(method)) {
            saveStudent(req, resp);
        } else if ("findStudentByNameAndPhone".equals(method)) {
            listStudents(req, resp);
        } else if ("findStudentByPoi".equals(method)) {
            findStudentByPoi(req, resp);
        } else if ("listStudentsByPage".equals(method)) {
            listStudentsByPage(req, resp);
        } else if ("deleteStudentInfoBySid".equals(method)) {
            deleteStudentInfoBySid(req, resp);
        } else if ("findOneStudentInfoBySid".equals(method)) {
            findOneStudentInfoBySid(req, resp);
        } else if ("updateOneStudent".equals(method)) {
            updateOneStudent(req, resp);
        }
    }

    /**
     * 保存学生信息
     *
     * @param req  请求对象
     * @param resp 响应对象
     * @throws ServletException Servlet对象
     * @throws IOException      IO对象
     */
    protected void saveStudent(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("********添加学生信息**********");
        // 1.获取前端请求参数
        String sname = req.getParameter("sname");
        String sex = req.getParameter("sex");
        String hobby = Arrays.toString(req.getParameterValues("hobby"));
        Date birthdate = java.sql.Date.valueOf(req.getParameter("birthdate"));
        String phone = req.getParameter("phone");
        String sdesc = req.getParameter("sdesc");
        int cid = Integer.parseInt(req.getParameter("cid"));

        // 2.封装为一个Student对象
        Student student = new Student(sname, sex, hobby, birthdate, phone, sdesc, cid);

        // 3.调用service层
        int rowCount = studentService.saveStudent(student);

        // 4.响应给前端
        resp.getWriter().println(rowCount);
    }

    /**
     * 根据姓名和手机号获取学生信息
     *
     * @param req  请求对象
     * @param resp 响应对象
     * @throws ServletException Servlet对象
     * @throws IOException      IO对象
     */
    protected void listStudents(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("********查询学生信息**********");
        // 1.获取前端请求参数
        String sname = req.getParameter("sname");
        String phone = req.getParameter("phone");

        // 3.调用service层
        List<Student> allStudent = studentService.findAllStudent(sname, phone);

        // 4.响应给前端
        String json = new Gson().toJson(allStudent);
        System.out.println("学生信息：" + json);
        resp.getWriter().println(json);
    }

    /**
     * 根据姓名和手机号获取学生信息并导出
     *
     * @param req  请求对象
     * @param resp 响应对象
     * @throws ServletException Servlet对象
     * @throws IOException      IO对象
     */
    protected void findStudentByPoi(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("********利用POI导出学生信息**********");
        // 1.获取前端请求参数
        String sname = req.getParameter("sname");
        String phone = req.getParameter("phone");
        // 3.调用service层
        List<Student> allStudent = studentService.findAllStudent(sname, phone);

        // 4.利用POI导出excel
        createExcel(allStudent, resp);
    }

    /**
     * 创建Excel
     * 将内存中内容写入硬盘
     *
     * @param list 导出的数据
     */
    private static void createExcel(List<Student> list, HttpServletResponse resp) throws IOException {
        // 创建一个Excel文件
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 创建一个工作表sheet
        HSSFSheet sheet = workbook.createSheet("学生表");
        // 控制列合并/行合并
        CellRangeAddress region = new CellRangeAddress(0, // 从第0行开始
                0, // 到第0行结束
                0, // 从第0列开始
                6 // 从第6列结束
        );
        sheet.addMergedRegion(region);


        // 在第0行第0列填入内容：学生信息
        HSSFRow hssfRow = sheet.createRow(0);
        HSSFCell headCell = hssfRow.createCell(0);
        headCell.setCellValue("学生信息");

        // 设置单元格格式居中
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        cellStyle.setFillBackgroundColor(HSSFColor.GREEN.index);
        cellStyle.setFillForegroundColor(HSSFColor.GREEN.index);

        HSSFFont font = workbook.createFont();
        font.setFontName("楷体"); // 字体
        font.setFontHeightInPoints((short) 30); // 字体大小
        font.setColor(HSSFColor.RED.index);// 颜色
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 加粗
        font.setItalic(true); // 倾斜
        cellStyle.setFont(font);
        // 设置第0行的样式
        headCell.setCellStyle(cellStyle);


        // 添加表头行（创建第1行）
        hssfRow = sheet.createRow(1);
        // 添加表头内容（给第一行的每个cell设置内容）
        headCell = hssfRow.createCell(0);
        headCell.setCellValue("姓名");
        headCell.setCellStyle(cellStyle);

        headCell = hssfRow.createCell(1);
        headCell.setCellValue("性别");
        headCell.setCellStyle(cellStyle);

        headCell = hssfRow.createCell(2);
        headCell.setCellValue("爱好");
        headCell.setCellStyle(cellStyle);

        headCell = hssfRow.createCell(3);
        headCell.setCellValue("出生日期");
        headCell.setCellStyle(cellStyle);

        headCell = hssfRow.createCell(4);
        headCell.setCellValue("手机号");
        headCell.setCellStyle(cellStyle);

        headCell = hssfRow.createCell(5);
        headCell.setCellValue("描述");
        headCell.setCellStyle(cellStyle);

        headCell = hssfRow.createCell(6);
        headCell.setCellValue("班级名称");
        headCell.setCellStyle(cellStyle);

        // 添加数据内容
        for (int i = 0; i < list.size(); i++) {
            hssfRow = sheet.createRow((int) i + 2);
            Student student = list.get(i);

            // 创建单元格，并设置值
            HSSFCell cell = hssfRow.createCell(0);
            cell.setCellValue(student.getSname());
            cell.setCellStyle(cellStyle);

            cell = hssfRow.createCell(1);
            cell.setCellValue(student.getSex());
            cell.setCellStyle(cellStyle);

            cell = hssfRow.createCell(2);
            cell.setCellValue(student.getHobby());
            cell.setCellStyle(cellStyle);

            cell = hssfRow.createCell(3);
            cell.setCellValue(student.getBirthdate());
            cell.setCellStyle(cellStyle);

            cell = hssfRow.createCell(4);
            cell.setCellValue(student.getPhone());
            cell.setCellStyle(cellStyle);

            cell = hssfRow.createCell(5);
            cell.setCellValue(student.getDesc());
            cell.setCellStyle(cellStyle);

            cell = hssfRow.createCell(6);
            cell.setCellValue(student.getClazz().getCname());
            cell.setCellStyle(cellStyle);
        }

        // 保存Excel文件
        try {
            // OutputStream outputStream = new FileOutputStream("D:/students.xls");
            OutputStream out = resp.getOutputStream();
            String fileName = "students.xls";
            resp.setContentType("application/vnd.ms-excel");
            resp.setHeader("Content-disposition", "attachment; fileName=" + fileName);

            workbook.write(out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 分页查询学生信息
     */
    protected void listStudentsByPage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("********分页查询学生信息**********");
        // 1.获取前端请求参数
        String sname = req.getParameter("sname");
        String phone = req.getParameter("phone");
        // 当前页
        int page = Integer.parseInt(req.getParameter("page"));
        System.out.println("当前页：" + page);
        // 2.定义每页显示3条记录
        int size = 3;
        System.out.println("每页展示条数：" + size);

        // 3.根据page、PageUtil工具类获得更多数据
        PageUtil pu = new PageUtil();
        // 设置page
        pu.setPage(page);
        // 设置size
        pu.setSize(size);
        // 获取startIndex
        int startIndex = pu.getStartIndex();
        System.out.println("当前索引值：" + startIndex);

        // 3.调用service层
        // 查询学生列表
        List<Student> allStudent = studentService.findStudentByPage(startIndex, size, sname, phone);
        // 查询学生总数
        int studentCount = studentService.findStudentCount();

        // 设置总条数
        pu.setTotalCount(studentCount);
        System.out.println("总条数：" + studentCount);
        // 设置总页数
        pu.setTotalPageCount();
        // 设置页码数组
        pu.setPageNums();
        // 获取页码数组
        int[] pageNums = pu.getPageNums();
        String s = "";
        for (int i = 0; i < pageNums.length; i++) {
            s += pageNums[i] + ",";
        }

        // 将数据放到分页工具类中
        pu.setList(allStudent);

        // 4.响应给前端
        String json = new Gson().toJson(pu);
        allStudent.stream().forEach(System.out::println);
        // 响应-因为前台发送的是ajax请求，所以这里响应的是json字符串
        resp.getWriter().println(json);
    }

    /**
     * 根据sid删除学生信息
     */
    protected void deleteStudentInfoBySid(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("-----根据Sid删除学生信息-----");
        // 获取请求参数
        int sid = Integer.parseInt(req.getParameter("sid"));
        // 调用service层
        int rowCount = studentService.deleteOneStudent(sid);
        System.out.println("删除时受影响行数：" + rowCount);
        // 响应-因为前台发送的是ajax请求，所以这里响应的是json字符串
        resp.getWriter().println(rowCount);
    }

    /**
     * 根据sid查询班级信息
     */
    protected void findOneStudentInfoBySid(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("-----查询单个学生信息-----");
        // 获取前端传递的请求参数
        int sid = Integer.parseInt(req.getParameter("sid"));
        // 调用service层
        Student oneStudent = studentService.findOneStudent(sid);
        System.out.println("学生信息：" + oneStudent);
        // 处理爱好
        String[] hobbies = oneStudent.getHobby().replaceAll("\\[|\\]", "").split(", ");
        List<String> hobbyList = Arrays.asList(hobbies);
        // 将学生信息放入请求域中
        req.setAttribute("oneStudent", oneStudent);
        req.setAttribute("hobbyList", hobbyList);
        // 请求转发到修改页面
        req.getRequestDispatcher("/updateStudent.jsp").forward(req, resp);
    }

    /**
     * 修改学生信息
     */
    protected void updateOneStudent(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("-----修改单个学生信息-----");
        // 获取前端传递的请求参数
        int sid = Integer.parseInt(req.getParameter("sid"));
        String sname = req.getParameter("sname");
        String sex = req.getParameter("sex");
        String hobby = Arrays.toString(req.getParameterValues("hobby"));
        java.util.Date birthdate = java.sql.Date.valueOf(req.getParameter("birthdate"));
        String phone = req.getParameter("phone");
        String desc = req.getParameter("sdesc");
        int cid = Integer.parseInt(req.getParameter("cid"));
        Student student = new Student(sid, sname, sex, hobby, birthdate, phone, desc, cid);
        // 调用service层
        int rowCount = studentService.updateStudent(student);
        System.out.println("修改学生信息受影响行数：" + rowCount);
        // 响应给前端
        resp.getWriter().println(rowCount);
    }
}
